package academic.ui.server.payment;

import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import academic.ui.server.UserManager;
import academic.ui.server.soco.PaymentInfo;
import ecommerce.soco.shared.NameValue;


import torque.generated.Creditcard;
import torque.generated.Orders;
import torque.generated.Paymentdetails;

public class AuthorizeNet {

	// Module name must be the same as the class name although it can be all in lowercase in order
    // to remain compatible with osCommerce.
    private static String code = "authorizenet";

    private static int sortOrder = -1;

    // The Authorize.Net Url used to POST the payment request.
    // "https://secure.authorize.net/gateway/transact.dll"
    private static String authorizeNetRequestUrl="https://test.authorize.net/gateway/transact.dll";

    // Login ID
    private static String authorizeNetLoginId="75sqQ96qHEP8";

    // Transaction Key
    private static String authorizeNetTxnKey="7r83Sb4HUd58Tz5p";

    // Test/Live Mode indicator
    private static boolean testMode = true;

    // Show the CVV entry field on the UI
    private static boolean showCVV = true;
        
    private static String DEFAULT_CURRENCY = "USD";
    
    private String DEFAULT_INVOICE_NUM = "0";
	
	  /**
     * Return a payment details object for Authorize.Net IPN module
     * 
     * @param order
     * @param info
     * @return Returns information in a PaymentDetails object
     * @throws Exception
     */
    public static PaymentInfo getPaymentDetails(Orders order) throws Exception
    {

        // Get the scale for currency calculations
        int scale = new Integer(2).intValue();

        PaymentInfo paymentDetails = new PaymentInfo();
        paymentDetails.setCode(code);
        //creditCardDetails.setPaymentType(PaymentDetails.SERVER_PAYMENT_GATEWAY);
        paymentDetails.setDescription("Authorize.Net");
        paymentDetails.setTitle("Authorize.Net");

        paymentDetails.setPostorget("post");
        paymentDetails.setRequesturl(authorizeNetRequestUrl);

        List<NameValue> parmList = new ArrayList<NameValue>();

        parmList.add(new NameValue("x_delim_data", URLEncoder.encode("True","UTF-8")));
        parmList.add(new NameValue("x_relay_response", URLEncoder.encode("False","UTF-8")));
        parmList.add(new NameValue("x_login", URLEncoder.encode(authorizeNetLoginId,"UTF-8")));
        parmList.add(new NameValue("x_tran_key", URLEncoder.encode(authorizeNetTxnKey,"UTF-8")));
        parmList.add(new NameValue("x_delim_char", URLEncoder.encode(",","UTF-8")));
        parmList.add(new NameValue("x_encap_char", URLEncoder.encode("","UTF-8")));
        parmList.add(new NameValue("x_method", URLEncoder.encode("CC","UTF-8")));
        parmList.add(new NameValue("x_type", URLEncoder.encode("AUTH_CAPTURE","UTF-8")));

        // AuthorizeNet requires details of the final price - inclusive of tax.
         BigDecimal total = order.getCurrencyValue().setScale(scale, BigDecimal.ROUND_HALF_UP);
               
        
        parmList.add(new NameValue("x_amount", URLEncoder.encode(total.toString(),"UTF-8")));
        parmList.add(new NameValue("x_currency_code", URLEncoder.encode(DEFAULT_CURRENCY,"UTF-8")));
        parmList.add(new NameValue("x_invoice_num", URLEncoder.encode(DEFAULT_CURRENCY,"UTF-8"))); // TODO
        parmList.add(new NameValue("x_test_request", (testMode ? URLEncoder.encode("TRUE","UTF-8") : URLEncoder.encode("FALSE","UTF-8"))));

        // Set the billing address

        // Set the billing name. If the name field consists of more than two strings, we take the
        // last one as being the surname.
        String bName = order.getCreditcard().getCcowner();
        if (bName != null)
        {
            String[] names = UserManager.getFirstLastFromFull(bName);
            if(names.length>=2) {
            	parmList.add(new NameValue("x_first_name", URLEncoder.encode(names[0],"UTF-8")));
            	parmList.add(new NameValue("x_last_name", URLEncoder.encode(names[1],"UTF-8")));
            }
            
        }
        parmList.add(new NameValue("x_company", URLEncoder.encode("","UTF-8")));
        parmList.add(new NameValue("x_city", URLEncoder.encode(order.getCreditcard().getBillingCity(),"UTF-8")));
        parmList.add(new NameValue("x_state", URLEncoder.encode(order.getCreditcard().getBillingState(),"UTF-8")));
        parmList.add(new NameValue("x_zip", URLEncoder.encode(order.getCreditcard().getBillingZip(),"UTF-8")));
        //parmList.add(new NameValue("x_phone", URLEncoder.encode(order.getCreditcard().get,"UTF-8")));
        parmList.add(new NameValue("x_cust_id", URLEncoder.encode(String.valueOf(order.getCustomersId()),"UTF-8")));
        parmList.add(new NameValue("x_email", URLEncoder.encode(order.getCustomers().getEmailAddress(),"UTF-8")));

        StringBuffer addrSB = new StringBuffer();
        addrSB.append(order.getCreditcard().getBillingAddress());

        if (addrSB.length() > 60)
        {
            parmList.add(new NameValue("x_address", URLEncoder.encode(addrSB.substring(0, 56) + "...","UTF-8")));
        } else
        {
            parmList.add(new NameValue("x_address", URLEncoder.encode(addrSB.toString(),"UTF-8")));
        }

        // Country requires the two letter country code
       
        parmList.add(new NameValue("x_country", URLEncoder.encode("US","UTF-8")));
        

        // Put the parameters into an array
        NameValue[] nvArray = new NameValue[parmList.size()];
        parmList.toArray(nvArray);
        paymentDetails.setParameters(nvArray);


        return paymentDetails;
    }

}
